Skip to content

pub async fn impl is monomorphized when func itself is monomorphized #143290

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

azhogin
Copy link
Contributor

@azhogin azhogin commented Jul 1, 2025

Implentation coroutine (func::{closure#0}) is monomorphized, when func itself is monomorphized.

Currently, when pub async fn foo(..) is exported from lib and used in several dependent crates, only 'header' function is monomorphized in the defining crate. 'header' function, returning coroutine object, is monomorphized, but the coroutine's poll function (which actually implements all the logic for the function) is not. In such situation, func::{closure#0} will be monomorphized in every dependency.

This PR adds monomorphization for func::{closure#0} (coroutine poll function), when func itself is monomorphized.

Simple test with one lib async function and ten dependent crates (executable) that use the function, shows 5-7% compilation time improvement (single-threaded).

@rustbot
Copy link
Collaborator

rustbot commented Jul 1, 2025

r? @oli-obk

rustbot has assigned @oli-obk.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 1, 2025
@oli-obk
Copy link
Contributor

oli-obk commented Jul 2, 2025

I don't think this needs a -Z flag. It makes a lot of sense to just change this everywhere. We can then benchmark it in the benchmark suite, too.

A similar change could be done for iterator or closure returning functions.

On that note: instead of collecting nested bodies in general, wouldn't it be slightly more correct to collect types that are in the opaque (non-opque types must already have all their impls monomorphized, as they are publicly reachable) return type of monomorphized functions? For opaque types we'd only need to monomorphize the trait impls that the opaque type has in its bounds

cc @compiler-errors for thoughts as you wrote #135314

@azhogin azhogin force-pushed the azhogin/link-pub-async-impls branch from d6bb74b to a6b81d5 Compare July 2, 2025 11:54
@rustbot
Copy link
Collaborator

rustbot commented Jul 2, 2025

Some changes occurred in coverage tests.

cc @Zalathar

@azhogin azhogin force-pushed the azhogin/link-pub-async-impls branch from a6b81d5 to d6e2c24 Compare July 2, 2025 11:55
@azhogin azhogin changed the title -Zlink-pub-async-impls flag added to monomorphize pub async fn impl pub async fn impl is monomorphized when func itself is monomorphized Jul 2, 2025
@azhogin
Copy link
Contributor Author

azhogin commented Jul 2, 2025

Flag removed, behaviour changed to be default.
"opaque return type of monomorphized functions" - not yet.

@rust-log-analyzer

This comment has been minimized.

@oli-obk
Copy link
Contributor

oli-obk commented Jul 2, 2025

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jul 2, 2025
@bors
Copy link
Collaborator

bors commented Jul 2, 2025

⌛ Trying commit d6e2c24 with merge 9443527...

bors added a commit that referenced this pull request Jul 2, 2025
pub async fn impl is monomorphized when func itself is monomorphized

Implentation coroutine (`func::{closure#0}`) is monomorphized, when func itself is monomorphized.

Currently, when `pub async fn foo(..)` is exported from lib and used in several dependent crates, only 'header' function is monomorphized in the defining crate. 'header' function, returning coroutine object, is monomorphized, but the coroutine's poll function (which actually implements all the logic for the function) is not. In such situation, `func::{closure#0}` will be monomorphized in every dependency.

This PR adds monomorphization for `func::{closure#0}` (coroutine poll function), when func itself is monomorphized.

Simple test with one lib async function and ten dependent crates (executable) that use the function, shows 5-7% compilation time improvement (single-threaded).
@bors
Copy link
Collaborator

bors commented Jul 2, 2025

☀️ Try build successful - checks-actions
Build commit: 9443527 (9443527f3f94abad97e5cecc88f429e299eac1f0)

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (9443527): comparison URL.

Overall result: ❌ regressions - please read the text below

Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.

Next Steps: If you can justify the regressions found in this try perf run, please do so in sufficient writing along with @rustbot label: +perf-regression-triaged. If not, please fix the regressions and do another perf run. If its results are neutral or positive, the label will be automatically removed.

@bors rollup=never
@rustbot label: -S-waiting-on-perf +perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
6.0% [0.8%, 13.6%] 6
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Max RSS (memory usage)

Results (primary -3.1%, secondary 2.4%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
2.4% [0.4%, 5.0%] 4
Improvements ✅
(primary)
-3.1% [-3.8%, -2.5%] 2
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -3.1% [-3.8%, -2.5%] 2

Cycles

Results (primary 2.5%, secondary 4.9%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
2.5% [2.0%, 3.7%] 11
Regressions ❌
(secondary)
5.6% [0.9%, 14.1%] 9
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-1.2% [-1.2%, -1.2%] 1
All ❌✅ (primary) 2.5% [2.0%, 3.7%] 11

Binary size

Results (secondary 9.4%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
9.4% [1.2%, 15.8%] 5
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Bootstrap: 462.08s -> 462.853s (0.17%)
Artifact size: 372.26 MiB -> 372.28 MiB (0.01%)

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels Jul 3, 2025
@oli-obk
Copy link
Contributor

oli-obk commented Jul 4, 2025

Some tests need blessing

The performance regression is expected, as the regressing benchmark has public async fn as a library build, and will thus now do the work that normally happened in the downstream crate.

@Zalathar
Copy link
Contributor

Zalathar commented Jul 6, 2025

In particular, you will need to set build.profiler = true in your bootstrap.toml config to properly bless the modified coverage test.

@azhogin azhogin force-pushed the azhogin/link-pub-async-impls branch from d6e2c24 to 57c2602 Compare July 8, 2025 19:25
@rust-log-analyzer

This comment has been minimized.

@azhogin
Copy link
Contributor Author

azhogin commented Jul 8, 2025

It looks like '-Z print-type-sizes' shows different results for x86_64 and aarch64 for some tests. Are there some helpfull flags to remove the difference between targets (except -C panic=abort)?

Also, I performed deeply-nested-multi test locally with one dependent crate with usage of main async func poll. And compilation time is the same (lib crate + use crate compilation with/without this change).

@oli-obk
Copy link
Contributor

oli-obk commented Jul 9, 2025

you could limit the test to one platform with //@only-x86_64

@azhogin azhogin force-pushed the azhogin/link-pub-async-impls branch from 57c2602 to e6b35f4 Compare July 9, 2025 11:23
@bors
Copy link
Collaborator

bors commented Jul 22, 2025

☔ The latest upstream changes (presumably #144249) made this pull request unmergeable. Please resolve the merge conflicts.

@oli-obk
Copy link
Contributor

oli-obk commented Jul 23, 2025

oh sorry I didn't realize you addressed this.

@bors delegate+

r=me after a rebase

@oli-obk
Copy link
Contributor

oli-obk commented Jul 26, 2025

@bors r+

@bors
Copy link
Collaborator

bors commented Jul 26, 2025

📌 Commit 4b3e42b has been approved by oli-obk

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jul 26, 2025
bors added a commit that referenced this pull request Jul 26, 2025
pub async fn impl is monomorphized when func itself is monomorphized

Implentation coroutine (`func::{closure#0}`) is monomorphized, when func itself is monomorphized.

Currently, when `pub async fn foo(..)` is exported from lib and used in several dependent crates, only 'header' function is monomorphized in the defining crate. 'header' function, returning coroutine object, is monomorphized, but the coroutine's poll function (which actually implements all the logic for the function) is not. In such situation, `func::{closure#0}` will be monomorphized in every dependency.

This PR adds monomorphization for `func::{closure#0}` (coroutine poll function), when func itself is monomorphized.

Simple test with one lib async function and ten dependent crates (executable) that use the function, shows 5-7% compilation time improvement (single-threaded).
@bors
Copy link
Collaborator

bors commented Jul 26, 2025

⌛ Testing commit 4b3e42b with merge 090c365...

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Collaborator

bors commented Jul 26, 2025

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Jul 26, 2025
@oli-obk
Copy link
Contributor

oli-obk commented Jul 26, 2025

@bors r-
@rustbot author

@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 26, 2025
@bors bors added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jul 26, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jul 26, 2025

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@azhogin azhogin force-pushed the azhogin/link-pub-async-impls branch from 4b3e42b to eaf2feb Compare July 26, 2025 14:54
@azhogin
Copy link
Contributor Author

azhogin commented Jul 26, 2025

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jul 26, 2025
@oli-obk
Copy link
Contributor

oli-obk commented Jul 27, 2025

@bors r+

@bors
Copy link
Collaborator

bors commented Jul 27, 2025

📌 Commit eaf2feb has been approved by oli-obk

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 27, 2025
bors added a commit that referenced this pull request Jul 27, 2025
pub async fn impl is monomorphized when func itself is monomorphized

Implentation coroutine (`func::{closure#0}`) is monomorphized, when func itself is monomorphized.

Currently, when `pub async fn foo(..)` is exported from lib and used in several dependent crates, only 'header' function is monomorphized in the defining crate. 'header' function, returning coroutine object, is monomorphized, but the coroutine's poll function (which actually implements all the logic for the function) is not. In such situation, `func::{closure#0}` will be monomorphized in every dependency.

This PR adds monomorphization for `func::{closure#0}` (coroutine poll function), when func itself is monomorphized.

Simple test with one lib async function and ten dependent crates (executable) that use the function, shows 5-7% compilation time improvement (single-threaded).
@bors
Copy link
Collaborator

bors commented Jul 27, 2025

⌛ Testing commit eaf2feb with merge da114a3...

@rust-log-analyzer
Copy link
Collaborator

The job x86_64-gnu-llvm-20-3 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
---- [ui] tests/ui/async-await/future-sizes/async-awaiting-fut.rs stdout ----
Saved the actual stdout to `/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/async-await/future-sizes/async-awaiting-fut/async-awaiting-fut.stdout`
diff of stdout:

49 print-type-size     variant `Panicked`: 1024 bytes
50 print-type-size         upvar `.arg`: 1024 bytes
51 print-type-size type: `std::task::Context<'_>`: 32 bytes, alignment: 8 bytes
- print-type-size     field `.waker`: 8 bytes
+ print-type-size     field `._marker2`: 0 bytes
53 print-type-size     field `.local_waker`: 8 bytes
- print-type-size     field `.ext`: 16 bytes
55 print-type-size     field `._marker`: 0 bytes
- print-type-size     field `._marker2`: 0 bytes
+ print-type-size     field `.ext`: 16 bytes
+ print-type-size     field `.waker`: 8 bytes
57 print-type-size type: `std::panic::Location<'_>`: 24 bytes, alignment: 8 bytes
- print-type-size     field `.filename`: 16 bytes
- print-type-size     field `.line`: 4 bytes
60 print-type-size     field `.col`: 4 bytes
+ print-type-size     field `.line`: 4 bytes
+ print-type-size     field `.filename`: 16 bytes
61 print-type-size     field `._filename`: 0 bytes
62 print-type-size type: `core::task::wake::ExtData<'_>`: 16 bytes, alignment: 8 bytes
63 print-type-size     variant `Some`: 16 bytes


The actual stdout differed from the expected stdout
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args async-await/future-sizes/async-awaiting-fut.rs`

error: 1 errors occurred comparing output.
status: exit status: 0
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage1/bin/rustc" "/checkout/tests/ui/async-await/future-sizes/async-awaiting-fut.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage1" "--target=x86_64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/async-await/future-sizes/async-awaiting-fut" "-A" "unused" "-A" "internal_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--edition=2021" "-C" "panic=abort" "-Z" "print-type-sizes" "--crate-type" "lib"
--- stdout -------------------------------
print-type-size type: `{async fn body of test()}`: 3078 bytes, alignment: 1 bytes
print-type-size     discriminant: 1 bytes
print-type-size     variant `Unresumed`: 0 bytes
print-type-size     variant `Suspend0`: 3077 bytes
print-type-size         local `.__awaitee`: 3077 bytes, type: {async fn body of calls_fut<{async fn body of big_fut()}>()}
print-type-size     variant `Returned`: 0 bytes
print-type-size     variant `Panicked`: 0 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes
print-type-size     field `.value`: 3077 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes
print-type-size     variant `MaybeUninit`: 3077 bytes
print-type-size         field `.uninit`: 0 bytes
print-type-size         field `.value`: 3077 bytes
print-type-size type: `{async fn body of calls_fut<{async fn body of big_fut()}>()}`: 3077 bytes, alignment: 1 bytes
print-type-size     discriminant: 1 bytes
print-type-size     variant `Unresumed`: 1025 bytes
print-type-size         upvar `.fut`: 1025 bytes
print-type-size     variant `Suspend0`: 2052 bytes
print-type-size         upvar `.fut`: 1025 bytes
print-type-size         local `.fut`: 1025 bytes
print-type-size         local `..coroutine_field4`: 1 bytes, type: bool
print-type-size         local `.__awaitee`: 1 bytes, type: {async fn body of wait()}
print-type-size     variant `Suspend1`: 3076 bytes
print-type-size         upvar `.fut`: 1025 bytes
print-type-size         padding: 1025 bytes
print-type-size         local `..coroutine_field4`: 1 bytes, alignment: 1 bytes, type: bool
print-type-size         local `.__awaitee`: 1025 bytes, type: {async fn body of big_fut()}
print-type-size     variant `Suspend2`: 2052 bytes
print-type-size         upvar `.fut`: 1025 bytes
print-type-size         local `.fut`: 1025 bytes
print-type-size         local `..coroutine_field4`: 1 bytes, type: bool
print-type-size         local `.__awaitee`: 1 bytes, type: {async fn body of wait()}
print-type-size     variant `Returned`: 1025 bytes
print-type-size         upvar `.fut`: 1025 bytes
print-type-size     variant `Panicked`: 1025 bytes
print-type-size         upvar `.fut`: 1025 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes
print-type-size     field `.value`: 1025 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes
print-type-size     variant `MaybeUninit`: 1025 bytes
print-type-size         field `.uninit`: 0 bytes
print-type-size         field `.value`: 1025 bytes
print-type-size type: `{async fn body of big_fut()}`: 1025 bytes, alignment: 1 bytes
print-type-size     discriminant: 1 bytes
print-type-size     variant `Unresumed`: 1024 bytes
print-type-size         upvar `.arg`: 1024 bytes
print-type-size     variant `Returned`: 1024 bytes
print-type-size         upvar `.arg`: 1024 bytes
print-type-size     variant `Panicked`: 1024 bytes
print-type-size         upvar `.arg`: 1024 bytes
print-type-size type: `std::task::Context<'_>`: 32 bytes, alignment: 8 bytes
print-type-size     field `._marker2`: 0 bytes
print-type-size     field `.local_waker`: 8 bytes
print-type-size     field `._marker`: 0 bytes
print-type-size     field `.ext`: 16 bytes
print-type-size     field `.waker`: 8 bytes
print-type-size type: `std::panic::Location<'_>`: 24 bytes, alignment: 8 bytes
print-type-size     field `.col`: 4 bytes
print-type-size     field `.line`: 4 bytes
print-type-size     field `.filename`: 16 bytes
print-type-size     field `._filename`: 0 bytes
print-type-size type: `core::task::wake::ExtData<'_>`: 16 bytes, alignment: 8 bytes
print-type-size     variant `Some`: 16 bytes
print-type-size         field `.0`: 16 bytes
print-type-size     variant `None`: 0 bytes
print-type-size         field `.0`: 0 bytes
print-type-size type: `std::panic::AssertUnwindSafe<core::task::wake::ExtData<'_>>`: 16 bytes, alignment: 8 bytes
print-type-size     field `.0`: 16 bytes
print-type-size type: `std::ptr::NonNull<str>`: 16 bytes, alignment: 8 bytes
print-type-size     field `.pointer`: 16 bytes
print-type-size type: `std::pin::Pin<&mut {async fn body of big_fut()}>`: 8 bytes, alignment: 8 bytes
print-type-size     field `.pointer`: 8 bytes
print-type-size type: `std::pin::Pin<&mut {async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 8 bytes, alignment: 8 bytes
print-type-size     field `.pointer`: 8 bytes
print-type-size type: `std::pin::Pin<&mut {async fn body of test()}>`: 8 bytes, alignment: 8 bytes
print-type-size     field `.pointer`: 8 bytes
print-type-size type: `std::pin::Pin<&mut {async fn body of wait()}>`: 8 bytes, alignment: 8 bytes
print-type-size     field `.pointer`: 8 bytes
print-type-size type: `std::ptr::DynMetadata<dyn std::any::Any>`: 8 bytes, alignment: 8 bytes
print-type-size     field `._vtable_ptr`: 8 bytes
print-type-size     field `._phantom`: 0 bytes
print-type-size type: `std::ptr::NonNull<std::ptr::metadata::VTable>`: 8 bytes, alignment: 8 bytes
print-type-size     field `.pointer`: 8 bytes
print-type-size type: `std::mem::ManuallyDrop<bool>`: 1 bytes, alignment: 1 bytes
print-type-size     field `.value`: 1 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes
print-type-size     field `.value`: 1 bytes
print-type-size type: `std::mem::MaybeUninit<bool>`: 1 bytes, alignment: 1 bytes
print-type-size     variant `MaybeUninit`: 1 bytes
print-type-size         field `.uninit`: 0 bytes
print-type-size         field `.value`: 1 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes
print-type-size     variant `MaybeUninit`: 1 bytes
print-type-size         field `.uninit`: 0 bytes
print-type-size         field `.value`: 1 bytes
print-type-size type: `std::task::Poll<()>`: 1 bytes, alignment: 1 bytes
print-type-size     discriminant: 1 bytes
print-type-size     variant `Ready`: 0 bytes
print-type-size         field `.0`: 0 bytes
print-type-size     variant `Pending`: 0 bytes
print-type-size type: `{async fn body of wait()}`: 1 bytes, alignment: 1 bytes
print-type-size     discriminant: 1 bytes
print-type-size     variant `Unresumed`: 0 bytes
print-type-size     variant `Returned`: 0 bytes
print-type-size     variant `Panicked`: 0 bytes
print-type-size type: `std::marker::PhantomData<&str>`: 0 bytes, alignment: 1 bytes
print-type-size type: `std::marker::PhantomData<*mut ()>`: 0 bytes, alignment: 1 bytes
print-type-size type: `std::marker::PhantomData<dyn std::any::Any>`: 0 bytes, alignment: 1 bytes
print-type-size type: `std::marker::PhantomData<fn(&()) -> &()>`: 0 bytes, alignment: 1 bytes
------------------------------------------
stderr: none


---- [ui] tests/ui/async-await/future-sizes/large-arg.rs stdout ----
Saved the actual stdout to `/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/async-await/future-sizes/large-arg/large-arg.stdout`
diff of stdout:

59 print-type-size     variant `Panicked`: 1024 bytes
60 print-type-size         upvar `.t`: 1024 bytes
61 print-type-size type: `std::task::Context<'_>`: 32 bytes, alignment: 8 bytes
- print-type-size     field `.waker`: 8 bytes
+ print-type-size     field `._marker2`: 0 bytes
63 print-type-size     field `.local_waker`: 8 bytes
- print-type-size     field `.ext`: 16 bytes
65 print-type-size     field `._marker`: 0 bytes
- print-type-size     field `._marker2`: 0 bytes
+ print-type-size     field `.ext`: 16 bytes
+ print-type-size     field `.waker`: 8 bytes
67 print-type-size type: `std::panic::Location<'_>`: 24 bytes, alignment: 8 bytes
- print-type-size     field `.filename`: 16 bytes
- print-type-size     field `.line`: 4 bytes
70 print-type-size     field `.col`: 4 bytes
+ print-type-size     field `.line`: 4 bytes
+ print-type-size     field `.filename`: 16 bytes
71 print-type-size     field `._filename`: 0 bytes
72 print-type-size type: `core::task::wake::ExtData<'_>`: 16 bytes, alignment: 8 bytes
73 print-type-size     variant `Some`: 16 bytes


The actual stdout differed from the expected stdout
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args async-await/future-sizes/large-arg.rs`

error: 1 errors occurred comparing output.
status: exit status: 0
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage1/bin/rustc" "/checkout/tests/ui/async-await/future-sizes/large-arg.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage1" "--target=x86_64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/async-await/future-sizes/large-arg" "-A" "unused" "-A" "internal_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--edition=2021" "-C" "panic=abort" "-Z" "print-type-sizes" "--crate-type=lib"
--- stdout -------------------------------
print-type-size type: `{async fn body of test()}`: 3076 bytes, alignment: 1 bytes
print-type-size     discriminant: 1 bytes
print-type-size     variant `Unresumed`: 0 bytes
print-type-size     variant `Suspend0`: 3075 bytes
print-type-size         local `.__awaitee`: 3075 bytes, type: {async fn body of a<[u8; 1024]>()}
print-type-size     variant `Returned`: 0 bytes
print-type-size     variant `Panicked`: 0 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes
print-type-size     field `.value`: 3075 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes
print-type-size     variant `MaybeUninit`: 3075 bytes
print-type-size         field `.uninit`: 0 bytes
print-type-size         field `.value`: 3075 bytes
print-type-size type: `{async fn body of a<[u8; 1024]>()}`: 3075 bytes, alignment: 1 bytes
print-type-size     discriminant: 1 bytes
print-type-size     variant `Unresumed`: 1024 bytes
print-type-size         upvar `.t`: 1024 bytes
print-type-size     variant `Suspend0`: 3074 bytes
print-type-size         upvar `.t`: 1024 bytes
print-type-size         local `.__awaitee`: 2050 bytes, type: {async fn body of b<[u8; 1024]>()}
print-type-size     variant `Returned`: 1024 bytes
print-type-size         upvar `.t`: 1024 bytes
print-type-size     variant `Panicked`: 1024 bytes
print-type-size         upvar `.t`: 1024 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes
print-type-size     field `.value`: 2050 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes
print-type-size     variant `MaybeUninit`: 2050 bytes
print-type-size         field `.uninit`: 0 bytes
print-type-size         field `.value`: 2050 bytes
print-type-size type: `{async fn body of b<[u8; 1024]>()}`: 2050 bytes, alignment: 1 bytes
print-type-size     discriminant: 1 bytes
print-type-size     variant `Unresumed`: 1024 bytes
print-type-size         upvar `.t`: 1024 bytes
print-type-size     variant `Suspend0`: 2049 bytes
print-type-size         upvar `.t`: 1024 bytes
print-type-size         local `.__awaitee`: 1025 bytes, type: {async fn body of c<[u8; 1024]>()}
print-type-size     variant `Returned`: 1024 bytes
print-type-size         upvar `.t`: 1024 bytes
print-type-size     variant `Panicked`: 1024 bytes
print-type-size         upvar `.t`: 1024 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes
print-type-size     field `.value`: 1025 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes
print-type-size     variant `MaybeUninit`: 1025 bytes
print-type-size         field `.uninit`: 0 bytes
print-type-size         field `.value`: 1025 bytes
print-type-size type: `std::task::Poll<[u8; 1024]>`: 1025 bytes, alignment: 1 bytes
print-type-size     discriminant: 1 bytes
print-type-size     variant `Ready`: 1024 bytes
print-type-size         field `.0`: 1024 bytes
print-type-size     variant `Pending`: 0 bytes
print-type-size type: `{async fn body of c<[u8; 1024]>()}`: 1025 bytes, alignment: 1 bytes
print-type-size     discriminant: 1 bytes
print-type-size     variant `Unresumed`: 1024 bytes
print-type-size         upvar `.t`: 1024 bytes
print-type-size     variant `Returned`: 1024 bytes
print-type-size         upvar `.t`: 1024 bytes
print-type-size     variant `Panicked`: 1024 bytes
print-type-size         upvar `.t`: 1024 bytes
print-type-size type: `std::task::Context<'_>`: 32 bytes, alignment: 8 bytes
print-type-size     field `._marker2`: 0 bytes
print-type-size     field `.local_waker`: 8 bytes
print-type-size     field `._marker`: 0 bytes
print-type-size     field `.ext`: 16 bytes
print-type-size     field `.waker`: 8 bytes
print-type-size type: `std::panic::Location<'_>`: 24 bytes, alignment: 8 bytes
print-type-size     field `.col`: 4 bytes
print-type-size     field `.line`: 4 bytes
print-type-size     field `.filename`: 16 bytes
print-type-size     field `._filename`: 0 bytes
print-type-size type: `core::task::wake::ExtData<'_>`: 16 bytes, alignment: 8 bytes
print-type-size     variant `Some`: 16 bytes
print-type-size         field `.0`: 16 bytes
print-type-size     variant `None`: 0 bytes
print-type-size         field `.0`: 0 bytes
print-type-size type: `std::panic::AssertUnwindSafe<core::task::wake::ExtData<'_>>`: 16 bytes, alignment: 8 bytes
print-type-size     field `.0`: 16 bytes
print-type-size type: `std::ptr::NonNull<str>`: 16 bytes, alignment: 8 bytes
print-type-size     field `.pointer`: 16 bytes
print-type-size type: `std::pin::Pin<&mut {async fn body of a<[u8; 1024]>()}>`: 8 bytes, alignment: 8 bytes
print-type-size     field `.pointer`: 8 bytes
print-type-size type: `std::pin::Pin<&mut {async fn body of b<[u8; 1024]>()}>`: 8 bytes, alignment: 8 bytes
print-type-size     field `.pointer`: 8 bytes
print-type-size type: `std::pin::Pin<&mut {async fn body of c<[u8; 1024]>()}>`: 8 bytes, alignment: 8 bytes
print-type-size     field `.pointer`: 8 bytes
print-type-size type: `std::pin::Pin<&mut {async fn body of test()}>`: 8 bytes, alignment: 8 bytes
print-type-size     field `.pointer`: 8 bytes
print-type-size type: `std::ptr::DynMetadata<dyn std::any::Any>`: 8 bytes, alignment: 8 bytes
print-type-size     field `._vtable_ptr`: 8 bytes
print-type-size     field `._phantom`: 0 bytes
print-type-size type: `std::ptr::NonNull<std::ptr::metadata::VTable>`: 8 bytes, alignment: 8 bytes
print-type-size     field `.pointer`: 8 bytes
print-type-size type: `std::task::Poll<()>`: 1 bytes, alignment: 1 bytes
print-type-size     discriminant: 1 bytes
print-type-size     variant `Ready`: 0 bytes
print-type-size         field `.0`: 0 bytes
print-type-size     variant `Pending`: 0 bytes
print-type-size type: `std::marker::PhantomData<&str>`: 0 bytes, alignment: 1 bytes
print-type-size type: `std::marker::PhantomData<*mut ()>`: 0 bytes, alignment: 1 bytes
print-type-size type: `std::marker::PhantomData<dyn std::any::Any>`: 0 bytes, alignment: 1 bytes
print-type-size type: `std::marker::PhantomData<fn(&()) -> &()>`: 0 bytes, alignment: 1 bytes
------------------------------------------
stderr: none


---- [ui] tests/ui/print_type_sizes/async.rs stdout ----
Saved the actual stdout to `/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/print_type_sizes/async/async.stdout`
diff of stdout:

17 print-type-size         field `.uninit`: 0 bytes
18 print-type-size         field `.value`: 8192 bytes
19 print-type-size type: `std::task::Context<'_>`: 32 bytes, alignment: 8 bytes
- print-type-size     field `.waker`: 8 bytes
+ print-type-size     field `._marker2`: 0 bytes
21 print-type-size     field `.local_waker`: 8 bytes
- print-type-size     field `.ext`: 16 bytes
23 print-type-size     field `._marker`: 0 bytes
- print-type-size     field `._marker2`: 0 bytes
+ print-type-size     field `.ext`: 16 bytes
+ print-type-size     field `.waker`: 8 bytes
25 print-type-size type: `std::panic::Location<'_>`: 24 bytes, alignment: 8 bytes
- print-type-size     field `.filename`: 16 bytes
- print-type-size     field `.line`: 4 bytes
28 print-type-size     field `.col`: 4 bytes
+ print-type-size     field `.line`: 4 bytes
+ print-type-size     field `.filename`: 16 bytes
29 print-type-size     field `._filename`: 0 bytes
30 print-type-size type: `core::task::wake::ExtData<'_>`: 16 bytes, alignment: 8 bytes
31 print-type-size     variant `Some`: 16 bytes


The actual stdout differed from the expected stdout
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args print_type_sizes/async.rs`

error: 1 errors occurred comparing output.
status: exit status: 0
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage1/bin/rustc" "/checkout/tests/ui/print_type_sizes/async.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage1" "--target=x86_64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/print_type_sizes/async" "-A" "unused" "-A" "internal_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--edition=2021" "-C" "panic=abort" "-Z" "print-type-sizes" "--crate-type" "lib"
--- stdout -------------------------------
print-type-size type: `{async fn body of test()}`: 16386 bytes, alignment: 1 bytes
print-type-size     discriminant: 1 bytes
print-type-size     variant `Unresumed`: 8192 bytes
print-type-size         upvar `.arg`: 8192 bytes
print-type-size     variant `Suspend0`: 16385 bytes
print-type-size         upvar `.arg`: 8192 bytes
print-type-size         local `.arg`: 8192 bytes
print-type-size         local `.__awaitee`: 1 bytes, type: {async fn body of wait()}
print-type-size     variant `Returned`: 8192 bytes
print-type-size         upvar `.arg`: 8192 bytes
print-type-size     variant `Panicked`: 8192 bytes
print-type-size         upvar `.arg`: 8192 bytes
print-type-size type: `std::mem::ManuallyDrop<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes
print-type-size     field `.value`: 8192 bytes
print-type-size type: `std::mem::MaybeUninit<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes
print-type-size     variant `MaybeUninit`: 8192 bytes
print-type-size         field `.uninit`: 0 bytes
print-type-size         field `.value`: 8192 bytes
print-type-size type: `std::task::Context<'_>`: 32 bytes, alignment: 8 bytes
print-type-size     field `._marker2`: 0 bytes
print-type-size     field `.local_waker`: 8 bytes
print-type-size     field `._marker`: 0 bytes
print-type-size     field `.ext`: 16 bytes
print-type-size     field `.waker`: 8 bytes
print-type-size type: `std::panic::Location<'_>`: 24 bytes, alignment: 8 bytes
print-type-size     field `.col`: 4 bytes
print-type-size     field `.line`: 4 bytes
print-type-size     field `.filename`: 16 bytes
print-type-size     field `._filename`: 0 bytes
print-type-size type: `core::task::wake::ExtData<'_>`: 16 bytes, alignment: 8 bytes
print-type-size     variant `Some`: 16 bytes
print-type-size         field `.0`: 16 bytes
print-type-size     variant `None`: 0 bytes
print-type-size         field `.0`: 0 bytes
print-type-size type: `std::panic::AssertUnwindSafe<core::task::wake::ExtData<'_>>`: 16 bytes, alignment: 8 bytes
print-type-size     field `.0`: 16 bytes
print-type-size type: `std::ptr::NonNull<str>`: 16 bytes, alignment: 8 bytes
print-type-size     field `.pointer`: 16 bytes
print-type-size type: `std::pin::Pin<&mut {async fn body of test()}>`: 8 bytes, alignment: 8 bytes
print-type-size     field `.pointer`: 8 bytes
print-type-size type: `std::pin::Pin<&mut {async fn body of wait()}>`: 8 bytes, alignment: 8 bytes
print-type-size     field `.pointer`: 8 bytes
print-type-size type: `std::ptr::DynMetadata<dyn std::any::Any>`: 8 bytes, alignment: 8 bytes
print-type-size     field `._vtable_ptr`: 8 bytes
print-type-size     field `._phantom`: 0 bytes
print-type-size type: `std::ptr::NonNull<std::ptr::metadata::VTable>`: 8 bytes, alignment: 8 bytes
print-type-size     field `.pointer`: 8 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes
print-type-size     field `.value`: 1 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes
print-type-size     variant `MaybeUninit`: 1 bytes
print-type-size         field `.uninit`: 0 bytes
print-type-size         field `.value`: 1 bytes
print-type-size type: `std::task::Poll<()>`: 1 bytes, alignment: 1 bytes
print-type-size     discriminant: 1 bytes
print-type-size     variant `Ready`: 0 bytes
print-type-size         field `.0`: 0 bytes
print-type-size     variant `Pending`: 0 bytes
print-type-size type: `{async fn body of wait()}`: 1 bytes, alignment: 1 bytes
print-type-size     discriminant: 1 bytes
print-type-size     variant `Unresumed`: 0 bytes
print-type-size     variant `Returned`: 0 bytes
print-type-size     variant `Panicked`: 0 bytes
print-type-size type: `std::marker::PhantomData<&str>`: 0 bytes, alignment: 1 bytes
print-type-size type: `std::marker::PhantomData<*mut ()>`: 0 bytes, alignment: 1 bytes
print-type-size type: `std::marker::PhantomData<dyn std::any::Any>`: 0 bytes, alignment: 1 bytes
print-type-size type: `std::marker::PhantomData<fn(&()) -> &()>`: 0 bytes, alignment: 1 bytes
------------------------------------------
stderr: none



@bors
Copy link
Collaborator

bors commented Jul 27, 2025

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Jul 27, 2025
@oli-obk
Copy link
Contributor

oli-obk commented Jul 28, 2025

hmm weird, there seems to be some reordering happening. I'm going on vacation in two days, but if you figure it out you can approve the PR yourself. If it's not clear where to start digging, best ask on zulip in the compiler stream

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
perf-regression Performance regression. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants